home *** CD-ROM | disk | FTP | other *** search
- /*
- Phonewrd - given a phone number, find all words or phrases in a dictionary
- which fit it.
-
- version 1.1 - 4/5/93
-
- Ported To Amiga.
- Christopher Klaus, cklaus@hotsun.nersc.gov or gt6468c@hydra.gatech.edu
- 26468 GaTech Station
- Atlanta, GA 30332
- (404)-676-9622
-
-
- (c) copyright 1993, Eric Haines, all rights reserved (erich@eye.com)
-
- See the man page for details.
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-
- /*============= default related =========================================== */
-
- /* path to dictionary */
- #define DICT_PATH "dict"
-
- /* number of digits in phone number */
- #define NUM_DIGITS 7
-
- /* how many numerals are allowed in our phrase? */
- #define NUMERALS_ALLOWED 0
-
- /* minimum length of words: note that 1 always gets bumped to 2, because of
- * OneLetter below.
- */
- #define MIN_LENGTH 1
-
- /* one letter words that are acceptable */
- #define ONE_LETTER "aio"
- /* If you like things like "CDB" (see the bee) or "IM4U, use or modify the
- * array below. Yes, "j" and "k" are potential names, "m" is only in "I am",
- * "q" is queue, etc - you decide... This option tends to generate lots of
- * useless goop, but it's good if you're desperate.
- */
- /* #define ONE_LETTER "abcdgimoptuxy248" */
-
- #define NO_NUMBER -2
-
- /* to make Q and Z not be anything, set them to NO_NUMBER, else set them
- * to the digit you want (e.g. 0 or 1)
- */
- #define Q NO_NUMBER
- #define Z NO_NUMBER
-
- /* translation table for letters to numbers */
- int Letter2Numeral[] =
- /* a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z */
- { 2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,Q,7,7,8,8,8,9,9,9,Z } ;
-
-
- /*============= storage space related ===================================== */
-
- #define MAX_DIGITS 14
- #define MAX_INDICES (((MAX_DIGITS+1)*MAX_DIGITS)/2)
-
- /* increment for word list memory space */
- #define WORD_LIST_SIZE 50
-
- /*============= internal use constants ==================================== */
-
- #define FIXED_LETTER -1
-
- #define BUFSIZE 256
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
-
- /*============= structures ================================================ */
-
- /* array of words, indexed by digit location and length of word. This list is
- * built up in the first part of the program, as each dictionary word is
- * categorized and put in its list. Then this structure is traversed to make
- * up the combinations.
- */
- typedef struct {
- char **p_word ; /* list of pointers to words */
- int count ; /* current count */
- int size ; /* allocated size */
- } wordlist, *p_wordlist ;
-
- /*============= data and macros =========================================== */
-
- #define IndexWL( digit_loc, length ) ( WLoffset[digit_loc] + length - 1 )
-
- wordlist WL[MAX_INDICES] ;
- int WLoffset[MAX_DIGITS] ;
- int PhoneNum[MAX_DIGITS+1] ; /* phone number translation */
- char PhoneStr[MAX_DIGITS+1] ; /* phone number letter, if specified */
- int NumeralMapped[10] ; /* if TRUE, then index # is mapped */
- char OneLetter[BUFSIZE] ;
- char DictPath[BUFSIZE] ;
- char *ProgName ;
-
- int NumDigits ;
- int NumIndices ;
- int NumNumerals ;
- int MinLength ;
- int RollOwn ;
- int Concat ;
- int Verbose ;
- int MatchTot ;
- int Wildcard ;
- int TotBrk ;
-
- int HoldSize ;
- int HoldCount ;
- char **HoldWord ;
-
- char OutputGrid[MAX_DIGITS][27] ;
-
- #define USAGE fprintf( stderr, "usage: %s [options] phone#[*...]\n" \
- " [*...] - extra *'s at the end mean optional wildcard letters\n" \
- " -l # - minimum length of words (cur. == %d)\n" \
- " -n # - number of numerals allowed in phrase (cur. == %d)\n" \
- " -q # - mapping of q (cur. == %d)\n" \
- " -z # - mapping of z (cur. == %d)\n" \
- " -d string - dictionary path (cur. == %s)\n" \
- " -s string - allowed single letter words (cur. == \"%s\")\n" \
- " -m char[26] - mapping of entire alphabet\n" \
- " -r - output the corresponding letters in an array\n" \
- " -c - output all combinations (no dictionary)\n" \
- " -v - verbose output (show words that do fit)\n" \
- , ProgName \
- , MinLength \
- , NumNumerals \
- , Q \
- , Z \
- , DictPath \
- , OneLetter \
- ) ;
-
- /*============= procedure declarations ==================================== */
-
- int phone_check() ;
- void roll_own() ;
- void concat_it() ;
- void concat_letter_out() ;
- void concat_letter_breaks_out() ;
- void init_wl() ;
- int fit_word() ;
- void search_for_match() ;
- void hold_word() ;
- void store_word() ;
- void free_wl() ;
- int scan_options() ;
-
- /*============= procedures ================================================ */
-
- main(argc,argv)
- int argc; char *argv[];
- {
- int nargc ;
- char *nargv[BUFSIZE], *targv ;
- int i, hdr_out ;
-
- ProgName = argv[1] ;
-
- HoldSize = HoldCount = 0 ;
-
- NumNumerals = NUMERALS_ALLOWED ;
- MinLength = MIN_LENGTH ;
- RollOwn = FALSE ;
- Concat = 0 ;
- Verbose = FALSE ;
-
- strcpy( OneLetter, ONE_LETTER ) ;
- strcpy( DictPath, DICT_PATH ) ;
-
- /* translate phone number */
- if ( argc < 2 ) {
- fprintf( stderr, "Not enough arguments.\n" ) ;
- USAGE ;
- return( 1 ) ;
- }
-
- if ( !scan_options( argc, argv, &nargc, nargv ) ) {
- return( 1 ) ;
- }
-
- if ( nargc < 1 ) {
- fprintf( stderr, "No phone number found.\n" ) ;
- USAGE ;
- return( 1 ) ;
- }
-
- /* loop through phone number(s), output headers if more than one */
- hdr_out = ( nargc > 1 ) ;
- for ( i = 0 ; i < nargc ; i++ ) {
- if ( i ) {
- /* output carriage returns before 2nd, 3rd, etc */
- fprintf( stdout, "\n" ) ;
- }
- targv = nargv[i] ;
- if ( hdr_out ) {
- fprintf( stdout, "# %s\n", targv ) ;
- }
- if ( phone_check( targv ) ) {
- /* something very bad happened, so quit */
- return( 1 ) ;
- }
- }
-
- return( 0 ) ;
- }
-
- int
- phone_check( numeral_string )
- char *numeral_string ;
- {
- int i, tot, word_count, length, min_length, found_digit, val ;
- char tchr, *tstr ;
- char dict_word[BUFSIZE] ;
- char out_string[BUFSIZE] ;
- p_wordlist p_wl ;
- FILE *infile ;
-
- NumDigits = 0 ;
- TotBrk = -1 ;
-
- tstr = numeral_string ;
- tchr = *tstr++ ;
- found_digit = FALSE ;
- while ( tchr != '\0' && tchr != '*' && (NumDigits <= MAX_DIGITS ) ) {
- if ( ( tchr >= '0' ) && ( tchr <= '9' ) ) {
- /* convert to digit */
- PhoneNum[NumDigits] = (int)(tchr - '0') ;
- PhoneStr[NumDigits++] = tchr ;
- found_digit = TRUE ;
- } else if ( ( (tchr >= 'A') && (tchr <= 'Z') ) ||
- ( (tchr >= 'a') && (tchr <= 'z') ) ) {
- PhoneNum[NumDigits] = FIXED_LETTER ;
- PhoneStr[NumDigits++] = tolower( tchr ) ;
- }
- tchr = *tstr++ ;
- }
- PhoneStr[NumDigits]='\0' ;
-
- if ( NumDigits <= 0 ) {
- fprintf( stderr, "Sorry, no digits input in `%s'\n", numeral_string ) ;
- fprintf( stderr, "Recompile with a higher MAX_DIGITS setting.\n" ) ;
- USAGE ;
- return(0) ;
- }
-
- /* check if we're in roll own mode */
- if ( RollOwn ) {
- roll_own() ;
- return(0) ;
- }
-
- /* check if we're in concat output mode */
- if ( Concat ) {
- concat_it() ;
- return(0) ;
- }
-
- /* check if any numbers were input */
- if ( !found_digit ) {
- /* entirely alphabetic input, so translate to number */
- for ( i = 0 ; i < NumDigits ; i++ ) {
- val = Letter2Numeral[PhoneStr[i]-'a'] ;
- if ( val != NO_NUMBER ) {
- fprintf( stdout, "%d", val ) ;
- } else {
- fprintf( stdout, "*" ) ;
- }
- }
- fprintf( stdout, "\n" ) ;
- return(0) ;
- }
-
- if ( tchr == '*' ) {
- /* the phone number ends in a wild card - phrases can be longer */
- Wildcard = 1 ;
- while ( *tstr++ == '*' ) {
- Wildcard++ ;
- }
- } else {
- Wildcard = 0 ;
- }
-
- if ( NumDigits > MAX_DIGITS ) {
- fprintf( stderr, "Sorry, too many digits input in `%s'; "
- "only %d allowed.\n", numeral_string, NumDigits ) ;
- USAGE ;
- return(0) ;
- }
-
- /* set up offset array for indexing WL */
- tot = 0 ;
- for ( i = 0 ; i < NumDigits ; i++ ) {
- WLoffset[i] = tot ;
- tot += (NumDigits-i) ;
- }
- NumIndices = ((NumDigits+1)*NumDigits)/2 ;
-
- /* build WL */
- word_count = 0 ;
- init_wl() ;
- infile = fopen( DictPath, "r") ;
- min_length = MinLength > 1 ? MinLength : 2 ;
- if ( infile != NULL ) {
- while ( fgets( dict_word, BUFSIZE, infile ) ) {
- word_count += fit_word( dict_word, min_length ) ;
- }
- } else {
- fprintf( stderr, "Sorry, couldn't find dictionary at `%s'.\n",
- DictPath ) ;
- return(1) ;
- }
- fclose( infile ) ;
-
- if ( Verbose ) {
- for ( i = 0 ; i < NumDigits ; i++ ) {
- for ( length = 1 ; length <= NumDigits-i ; length++ ) {
- p_wl = &WL[IndexWL( i, length )] ;
- if ( p_wl->count ) {
- fprintf( stdout, "\nDigit %d, length %d:\n", i+1, length ) ;
- for ( tot = 0 ; tot < p_wl->count ; tot++ ) {
- fprintf( stdout, " %s\n", p_wl->p_word[tot] ) ;
- }
- }
- }
- }
- }
-
- MatchTot = 0 ; /* number of words matched */
-
- /* search through WL for paths */
- if ( word_count ) {
- /* good, there's something to work with: search away! */
- *out_string = '\0' ;
- search_for_match( 0, out_string, out_string, 0 ) ;
- if ( !MatchTot ) {
- fprintf( stderr,
- "Bad luck: dictionary words fit, but there's too much "
- "numeral goop.\n" ) ;
- fprintf( stderr,
- "I'd try again with the option `-n %d' or so.\n",
- NumNumerals+1 ) ;
- }
- } else {
- fprintf( stderr,
- "Worst luck: no dictionary words fit anywhere in %s.\n",
- PhoneStr ) ;
- fprintf( stderr,
- "Maybe try again with the option `-s abcdgimoptuxy248'.\n" ) ;
- }
-
- free_wl() ;
-
- return(0) ;
- }
-
- void
- roll_own()
- {
- int digit_letter[MAX_DIGITS], found_one, search, i, j, k ;
-
- for ( i = 0 ; i < NumDigits ; i++ ) {
- if ( PhoneNum[i] == FIXED_LETTER ) {
- digit_letter[i] = -2 ;
- } else {
- digit_letter[i] = -1 ;
- }
- }
- found_one = TRUE ;
- for ( i = 0 ; i < 26 && found_one ; i++ ) {
- found_one = FALSE ;
- for ( j = 0 ; j < NumDigits ; j++ ) {
- if ( digit_letter[j] >= 26 ) {
- /* done with this one */
- fprintf( stdout, " " ) ;
- } else {
- if ( digit_letter[j] == -2 ) {
- found_one = TRUE ;
- digit_letter[j] = 26 ;
- fprintf( stdout, " %c", PhoneStr[j] ) ;
- } else {
- for ( k = digit_letter[j] + 1, search = TRUE
- ; k < 26 && search
- ; k++ ) {
-
- if ( Letter2Numeral[k] == PhoneNum[j] ) {
- search = FALSE ;
- found_one = TRUE ;
- fprintf( stdout, " %c", (char)(k+'a') ) ;
- digit_letter[j] = k ;
- }
- }
- if ( search ) {
- /* no further match found */
- if ( digit_letter[j] < 0 ) {
- /* numeral is not mapped, so output it directly */
- fprintf( stdout, " %c", PhoneStr[j] ) ;
- }
- digit_letter[j] = 26 ;
- }
- }
- }
- }
- fprintf( stdout, "\n" ) ;
- }
- }
-
- void
- concat_it()
- {
- int i, j, tot ;
- char full_string[MAX_DIGITS+1] ;
-
- for ( i = 0 ; i < NumDigits ; i++ ) {
- if ( PhoneNum[i] == FIXED_LETTER ) {
- OutputGrid[i][0] = PhoneStr[i] ;
- OutputGrid[i][1] = '\0' ;
- } else {
- tot = 0 ;
- for ( j = 0 ; j < 26 ; j++ ) {
- if ( Letter2Numeral[j] == PhoneNum[i] ) {
- OutputGrid[i][tot++] = (char)(j+'a') ;
- }
- }
- if ( !tot ) {
- /* no match found */
- OutputGrid[i][tot++] = PhoneStr[i] ;
- }
- OutputGrid[i][tot] = '\0' ;
- }
- }
-
- if ( Concat == 1 ) {
- concat_letter_out( 0, full_string ) ;
- } else {
- concat_letter_breaks_out( 0, full_string ) ;
- }
- }
-
- void
- concat_letter_out( digit, full_string )
- int digit ;
- char *full_string ;
- {
- int i, length ;
- char *cstr ;
-
- if ( digit >= NumDigits ) {
- full_string[digit] = '\0' ;
- fprintf( stdout, "%s\n", full_string ) ;
- } else {
- length = strlen( cstr = OutputGrid[digit] ) ;
- for ( i = 0 ; i < length ; i++ ) {
- full_string[digit] = *cstr++ ;
- concat_letter_out( digit+1, full_string ) ;
- }
- }
- }
-
- void
- concat_letter_breaks_out( digit, full_string )
- int digit ;
- char *full_string ;
- {
- char brk_string[MAX_DIGITS*2] ;
- int i, j, bny, index, length ;
- char *cstr ;
-
- if ( digit >= NumDigits ) {
- if ( TotBrk == -1 ) {
- TotBrk = 1 ;
- for ( i = 1 ; i < NumDigits ; i++ ) {
- TotBrk *= 2 ;
- }
- }
- for ( i = 0 ; i < TotBrk ; i++ ) {
- bny = i ;
- index = 0 ;
- for ( j = 0 ; j < NumDigits ; j++ ) {
- brk_string[index++] = full_string[j] ;
- if ( bny & 0x1 ) {
- brk_string[index++] = ' ' ;
- }
- bny = bny >> 1 ;
- }
- brk_string[index] = '\0' ;
- fprintf( stdout, "%s\n", brk_string ) ;
- }
- } else {
- length = strlen( cstr = OutputGrid[digit] ) ;
- for ( i = 0 ; i < length ; i++ ) {
- full_string[digit] = *cstr++ ;
- concat_letter_breaks_out( digit+1, full_string ) ;
- }
- }
- }
-
- /* create structures needed for the word list, etc */
- void
- init_wl()
- {
- p_wordlist p_wl ;
- int i, j, length, search ;
- char tstr[2] ;
-
- for ( i = 0, p_wl = WL ; i < NumIndices ; i++, p_wl++ ) {
- p_wl->p_word = NULL ;
- p_wl->count = 0 ;
- p_wl->size = 0 ;
- }
-
- /* figure out which numerals don't have any letter translations */
- for ( i = 0 ; i < 10 ; i++ ) {
- for ( j = 0, search = TRUE ; j < 26 && search ; j++ ) {
- if ( i == Letter2Numeral[j] ) {
- search = FALSE ;
- }
- }
- /* set to TRUE if numeral is mapped by something */
- NumeralMapped[i] = !search ;
- }
-
- tstr[1] = '\0' ;
- /* add one number values as possible */
- /* we rely on the fact that the first word in the single letter word
- * lists is actually a numeral, so change the following at your own
- * peril.
- */
- for ( i = 0 ; i < 10 ; i++ ) {
- tstr[0] = (char)i + '0' ;
- (void)fit_word( tstr, 1 ) ;
- }
-
- /* add one letter words as possible */
- length = strlen( OneLetter ) ;
- for ( i = 0 ; i < length ; i++ ) {
- tstr[0] = OneLetter[i] ;
- (void)fit_word( tstr, 1 ) ;
- }
- }
-
- /* see if the word fits in the database anywhere */
- int
- fit_word( dict_word, min_length )
- char *dict_word ;
- int min_length ;
- {
- int length, compare_length, true_length, index_length, nl ;
- int i, j ;
- int word_val[MAX_DIGITS], hit[MAX_DIGITS], *wv, check_length, match, tot ;
- char lc_dict_word[MAX_DIGITS], *wc, *lc, tchr, *cc ;
- char clean_dict_word[BUFSIZE] ;
-
- /* convert word to numbers */
- length = strlen( dict_word ) ;
- compare_length = true_length = 0 ;
- for ( i = 0, wv = word_val, wc = dict_word, lc = lc_dict_word,
- cc = clean_dict_word
- ; ( i < length ) && ( compare_length < NumDigits )
- ; i++, wc++ ) {
-
- /* remove apostrophes, hyphens, etc for matching */
- tchr = tolower(*wc) ;
- if ( ( tchr >= 'a' ) && ( tchr <= 'z' ) ) {
- *wv++ = Letter2Numeral[(*lc++ = tchr) -'a'] ;
- compare_length++ ;
- } else if ( ( tchr >= '0' ) && ( tchr <= '9' ) ) {
- *wv++ = (*lc++ = tchr) -'0' ;
- compare_length++ ;
- }
-
- /* clean the word of any carriage return junk */
- if ( tchr > 13 ) {
- *cc++ = *wc ;
- }
- }
- true_length = compare_length ;
-
- while ( *wc ) {
- tchr = tolower( *wc++ ) ;
- /* get true length of word in valid characters */
- if ( ( tchr >= 'a' ) && ( tchr <= 'z' ) ) {
- true_length++ ;
- } else if ( ( tchr >= '0' ) && ( tchr <= '9' ) ) {
- true_length++ ;
- }
- /* copy the rest of the word */
- if ( tchr > 13 ) {
- *cc++ = tchr ;
- }
- }
- /* end the cleaned word */
- *cc = '\0' ;
-
- /* is the word too long? */
- if ( true_length > NumDigits + Wildcard ) {
- /* the word was too long */
- return( 0 ) ;
- }
-
- /* is the word too short? */
- if ( true_length < min_length ) {
- /* the word was too short */
- return( 0 ) ;
- }
-
- /* now look for matches */
- if ( Wildcard ) {
- check_length = NumDigits - true_length + Wildcard ;
- if ( check_length >= NumDigits ) {
- /* cannot index into array at higher than NumDigits-1, so reduce */
- check_length = NumDigits - 1 ;
- }
- } else {
- check_length = NumDigits - true_length ;
- }
-
- for ( i = 0, tot = 0 ; i <= check_length ; i++ ) {
- index_length = compare_length+i ;
- if ( Wildcard ) {
- if ( index_length > NumDigits ) {
- /* cut comparisons down to numerals available */
- index_length = NumDigits ;
- }
- }
- for ( j = i, wv = word_val, match = TRUE
- ; match && (j < index_length)
- ; j++, wv++ ) {
-
- /* numerical match? */
- if ( PhoneNum[j] != *wv ) {
- /* no; exact letter match? */
- if ( ( PhoneNum[j] != FIXED_LETTER ) ||
- ( PhoneStr[j] != lc_dict_word[j-i] ) ) {
- /* no match, stop testing */
- match = FALSE ;
- }
- }
- }
- if ( match ) {
- /* word fits, store index */
- hit[tot++] = i ;
- }
- }
- /* were there any matches? */
- if ( tot ) {
- /* make one copy of the word */
- wc = strdup( clean_dict_word ) ;
- hold_word( wc ) ;
- for ( i = 0 ; i < tot ; i++ ) {
- if ( Wildcard ) {
- if ( hit[i] + true_length <= NumDigits ) {
- nl = true_length ;
- } else {
- nl = NumDigits - hit[i] ;
- }
- store_word( wc, hit[i], nl ) ;
- } else {
- store_word( wc, hit[i], true_length ) ;
- }
- }
- }
-
- return( tot ) ;
- }
-
- /* yeah, I could combine this with store_word - call me lazy... */
- void
- hold_word( word )
- char *word ;
- {
- if ( HoldSize <= HoldCount ) {
- if ( HoldSize ) {
- HoldSize += WORD_LIST_SIZE * NumDigits ;
- HoldWord = (char **)realloc( (void *)HoldWord,
- HoldSize * sizeof(char *)) ;
- } else {
- HoldSize = WORD_LIST_SIZE * NumDigits ;
- HoldWord =
- (char **)malloc( HoldSize * sizeof(char *)) ;
- }
- if ( HoldWord == NULL ) {
- fprintf( stderr, "Ugh, we're out of memory!\n" ) ;
- exit(1) ;
- }
- }
- HoldWord[HoldCount++] = word ;
- }
-
- /* store word in the given location */
- void
- store_word( word, digit, length )
- char *word ;
- int digit ;
- int length ;
- {
- p_wordlist p_wl ;
-
- p_wl = &WL[IndexWL( digit, length )] ;
- /* check storage space */
- if ( p_wl->size <= p_wl->count ) {
- if ( p_wl->size ) {
- p_wl->size += WORD_LIST_SIZE ;
- p_wl->p_word = (char **)realloc( (void *)p_wl->p_word,
- p_wl->size * sizeof(char *)) ;
- } else {
- p_wl->size = WORD_LIST_SIZE ;
- p_wl->p_word =
- (char **)malloc( p_wl->size * sizeof(char *)) ;
- }
- if ( p_wl->p_word == NULL ) {
- fprintf( stderr, "Ugh, we're out of memory!\n" ) ;
- exit(1) ;
- }
- }
- /* store word in structure */
- p_wl->p_word[p_wl->count++] = word ;
- }
-
- /* search through the stored words for matches */
- void
- search_for_match( digit, full_string, suffix_loc, numeral_count )
- int digit ;
- char *full_string ;
- char *suffix_loc ;
- int numeral_count ;
- {
- int length, tot_len, tot_word, wn, add_num, add_val ;
- p_wordlist p_wl ;
- char **p_word ;
-
- tot_len = NumDigits - digit ;
- /* loop through all possible word lengths from this point */
- /* count down so that the longer strings are output first */
- for ( length = tot_len ; length > 0 ; length-- ) {
- p_wl = &WL[IndexWL( digit, length )] ;
- tot_word = p_wl->count ;
- /* now go through all words on the list */
- if ( length == 1 ) {
- /* is the numeral of the first word mapped? */
- if ( NumeralMapped[**(p_wl->p_word)-'0'] ) {
- /* don't include first word (a mapped numeral) if we've used
- * up our quota.
- */
- wn = (numeral_count >= NumNumerals ) ;
- add_num = 1 ;
- } else {
- /* an unmapped numeral, so definitely do it */
- wn = 0 ;
- add_num = 0 ;
- }
- } else {
- /* not on the one letter word list, so do all words */
- wn = 0 ;
- add_num = 0 ;
- }
- for ( p_word = p_wl->p_word + wn
- ; wn < tot_word
- ; wn++, p_word++ ) {
-
- strcpy( suffix_loc, *p_word ) ;
- if ( length == tot_len ) {
- /* finished - output it! */
- fprintf( stdout, "%s\n", full_string ) ;
- MatchTot++ ;
- } else {
- strcat( suffix_loc, " " ) ;
- /* Add one to numeral_count only if numeral is used */
- search_for_match( digit+length, full_string,
- suffix_loc + strlen( suffix_loc ),
- numeral_count + add_num ) ;
- }
- }
- }
- }
-
- void
- free_wl()
- {
- int i ;
- p_wordlist p_wl ;
-
- for ( i = 0, p_wl = WL ; i < NumIndices ; i++, p_wl++ ) {
- if ( p_wl->size ) {
- p_wl->size = 0 ;
- p_wl->count = 0 ;
- free( p_wl->p_word ) ;
- }
- }
-
- /* the only function of HoldWord is to be able to free the word memory */
- if ( HoldSize ) {
- for ( i = 0 ; i < HoldCount ; i++ ) {
- free( HoldWord[i] ) ;
- }
- free( HoldWord ) ;
- }
- HoldCount = HoldSize = 0 ;
- }
-
- /* strip out all valid "-" arguments and their values */
- int
- scan_options( argc, argv, nargc, nargv )
- int argc ;
- char *argv[] ;
- int *nargc ;
- char *nargv[] ;
- {
- int num_arg ;
- int i ;
- char str[BUFSIZE] ;
-
- *nargc = num_arg = 0 ;
-
- while ( ++num_arg < argc ) {
- if ( *argv[num_arg] == '-' ) {
- switch( argv[num_arg][1] ) {
- case 'l': /* minimum length of words */
- if ( ++num_arg < argc ) {
- sscanf( argv[num_arg], "%d", &i ) ;
- if ( i < 1 ) {
- fprintf( stderr,
- "Minimum word length too low!\n" ) ;
- USAGE ;
- return( FALSE ) ;
- }
- MinLength = i ;
- }
- break ;
- case 'n': /* number of numerals allowed */
- if ( ++num_arg < argc ) {
- sscanf( argv[num_arg], "%d", &i ) ;
- if ( i < 0 ) {
- fprintf( stderr, "Number of numerals too low!\n" ) ;
- USAGE ;
- return( FALSE ) ;
- }
- NumNumerals = i ;
- }
- break ;
- case 'q': /* mapping of q */
- if ( ++num_arg < argc ) {
- sscanf( argv[num_arg], "%d", &i ) ;
- if ( (i >= 0) && (i <= 9) ) {
- Letter2Numeral['q'-'a'] = i ;
- }
- }
- break ;
- case 'z': /* mapping of z */
- if ( ++num_arg < argc ) {
- sscanf( argv[num_arg], "%d", &i ) ;
- if ( (i >= 0) && (i <= 9) ) {
- Letter2Numeral['z'-'a'] = i ;
- }
- }
- break ;
- case 'd': /* dictionary path */
- if ( ++num_arg < argc ) {
- sscanf( argv[num_arg], "%s", DictPath ) ;
- }
- break ;
- case 's': /* allowed single letter words */
- if ( ++num_arg < argc ) {
- sscanf( argv[num_arg], "%s", OneLetter ) ;
- }
- break ;
- case 'm': /* mapping of entire alphabet */
- if ( ++num_arg < argc ) {
- sscanf( argv[num_arg], "%s", str ) ;
- if ( strlen(str) != 26 ) {
- fprintf( stderr, "Must input all 26 digits\n" ) ;
- USAGE ;
- return( FALSE ) ;
- }
- for ( i = 0 ; i < 26 ; i++ ) {
- if ( (str[i] >= '0') && (str[i] <= '9') ) {
- Letter2Numeral[i] = str[i] - '0' ;
- } else {
- Letter2Numeral[i] = NO_NUMBER ;
- }
- }
- if ( Verbose ) {
- fprintf( stderr, "here's your banana: )\n" ) ;
- }
- }
- break ;
- case 'r': /* output concatenation */
- RollOwn = TRUE ;
- break ;
- case 'c': /* output concatenation */
- Concat = 1 ;
- break ;
- case 'C': /* output spacing & concatenation */
- Concat = 2 ;
- break ;
- case 'v': /* verbose output */
- Verbose = TRUE ;
- break ;
- default:
- fprintf( stderr, "No such option `-%c'\n",
- argv[num_arg][1] ) ;
- USAGE ;
- return( FALSE ) ;
- }
- } else {
- /* not an argument, so pass it on */
- nargv[(*nargc)++] = argv[num_arg] ;
- }
- }
- return( TRUE ) ;
- }
-